package org.agora.games.bodybuilder.geometry;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import svg.parser.Vertex;

import java.awt.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @author : Arash Bizhanzadeh <arash.bizhanzadeh@cbc.ca>
 *         Date: 12-01-11
 *         Time: 8:53 PM
 */
public class FixtureDefinition {
    private static Logger logger = LoggerFactory.getLogger(FixtureDefinition.class);
    private Vertex  center;
    private ArrayList<Vertex> perimeter;
    private float density;
    private float friction;
    private float restitution;
    private Color color;


    public FixtureDefinition(Vertex center, ArrayList<Vertex> perimeter, 
                             float density, float friction, float restitution) {

        this.center = center;
        this.perimeter = perimeter;
        this.density = density;
        this.friction = friction;
        this.restitution = restitution;

    }

    //http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
    public boolean contains(Vertex v){
        logger.debug("Checking inside polygon");
                int i ;
                  for (i = 0; i< perimeter.size()-1 ; i++) {
                    if ( ((perimeter.get(i).y>v.y) != (perimeter.get(i + 1).y > v.y)) &&
                	 (v.x < ((perimeter.get(i+1).x - perimeter.get(i).x) *
                             (v.y -perimeter.get(i).y) / (perimeter.get(i+1).y-perimeter.get(i).y) +
                             perimeter.get(i).x)) ){
                        logger.debug("inside polygon");
                       return true;
                    }
                  }
                return false;
    }
    
    public Vertex isOnRadiusLine(Vertex v){
        for( Vertex perim : perimeter){ 
                float  lowerX = center.x < perim.x ? center.x : perim.x;
                float higherX = center.x > perim.x ? center.x : perim.x;
                float higherY = center.y > perim.y ? center.y: perim.y;
                float lowerY = center.y < perim.y ? center.y : perim.y;
                if(distanceFromLine(center, perim, v) < 3){
                    if(v.x >= lowerX && v.x <= higherX ){
                        if( v.y >= lowerY && v.y <= higherY){
                            return perim;
                        }
                    }
                }
        }
        return null;

    }


    public Vertex hasVertexLike(Vertex point) {
        for( Vertex v : perimeter){
            if(point.distance(v) < 3){
                logger.debug("vertex matched : {},{}",v.x,v.y);
                return v;
            }
        }
        return null;
    }


    double distanceFromLine(Vertex start, Vertex end,Vertex v) {
            //ax+by+c = 0
            double a, b, c;
            if (start.y == end.y) {
                b = 1;
                a = 0;
            } else {
                b = -(start.x - end.x) / (start.y - end.y);
                a = 1;
            }
            c = (b * (start.y + end.y) + a * (start.x + end.x)) / -2;
         return Math.abs(a * v.x + b * v.y + c) / Math.sqrt(a * a + b * b);
    
        }
    public Vertex getCenter() {
        return center;
    }

    public ArrayList<Vertex> getPerimeter() {
        return perimeter;
    }

    public float getDensity() {
        return density;
    }

    public float getFriction() {
        return friction;
    }

    public float getRestitution() {
        return restitution;
    }

    public Color getColor() {
        return color;
    }

    public void setColor(Color aColor) {
        this.color = aColor;
    }
}
